package org.csu.mypetstore.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.csu.mypetstore.api.common.CommonResponse;
import org.csu.mypetstore.api.entity.LineItem;
import org.csu.mypetstore.api.entity.Order;
import org.csu.mypetstore.api.entity.OrderStatus;
import org.csu.mypetstore.api.entity.Sequence;
import org.csu.mypetstore.api.persistence.LineItemMapper;
import org.csu.mypetstore.api.persistence.OrderMapper;
import org.csu.mypetstore.api.persistence.OrderStatusMapper;
import org.csu.mypetstore.api.persistence.SequenceMapper;
import org.csu.mypetstore.api.service.OrderService;
import org.csu.mypetstore.api.vo.OrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderStatusMapper orderStatusMapper;
    @Autowired
    SequenceMapper sequenceMapper;
    @Autowired
    LineItemMapper lineItemMapper;

    private OrderVO orderToOrderVO( Order order, OrderStatus status, List<LineItem> lineItemList ){
        OrderVO orderVO = new OrderVO();
        orderVO.setOrderId( order.getOrderId() );
        orderVO.setUsername( order.getUsername() );
        orderVO.setOrderDate( order.getOrderDate() );
        orderVO.setShipAddress1( order.getShipAddress1() );
        orderVO.setShipAddress2( order.getShipAddress2() );
        orderVO.setShipCity( order.getShipCity() );
        orderVO.setShipState( order.getShipState() );
        orderVO.setShipZip( order.getShipZip() );
        orderVO.setShipCountry( order.getShipCountry() );
        orderVO.setBillAddress1( order.getBillAddress1() );
        orderVO.setBillAddress2( order.getBillAddress2() );
        orderVO.setBillState( order.getBillState() );
        orderVO.setBillCity( order.getBillCity() );
        orderVO.setBillZip( order.getBillZip() );
        orderVO.setBillCountry( order.getBillCountry() );
        orderVO.setCourier( order.getCourier() );
        orderVO.setTotalPrice( order.getTotalPrice() );
        orderVO.setBillToFirstName( order.getBillToFirstName() );
        orderVO.setBillToLastName( order.getBillToLastName() );
        orderVO.setShipToFirstName( order.getShipToFirstName() );
        orderVO.setShipToLastName( order.getShipToLastName() );
        orderVO.setCreditCard( order.getCreditCard() );
        orderVO.setExpiryDate( order.getExpiryDate() );
        orderVO.setCardType( order.getCardType() );
        orderVO.setLocale( order.getLocale() );
        orderVO.setAlipayOutTradeNo( order.getAlipayOutTradeNo() );

        orderVO.setStatus( status.getStatus() );
        orderVO.setLineItems( lineItemList );

        return orderVO;

    }

    private Order orderVoToOrder(OrderVO vo){
        Order order = new Order();
        order.setOrderId( vo.getOrderId() );
        order.setUsername( vo.getUsername() );
        order.setOrderDate( vo.getOrderDate() );
        order.setShipAddress1( vo.getShipAddress1() );
        order.setShipAddress2( vo.getShipAddress2() );
        order.setShipCity( vo.getShipCity() );
        order.setShipState( vo.getShipState() );
        order.setShipZip( vo.getShipZip() );
        order.setShipCountry( vo.getShipCountry() );
        order.setBillAddress1( vo.getBillAddress1() );
        order.setBillAddress2( vo.getBillAddress2() );
        order.setBillState( vo.getBillState() );
        order.setBillCity( vo.getBillCity() );
        order.setBillZip( vo.getBillZip() );
        order.setBillCountry( vo.getBillCountry() );
        order.setCourier( vo.getCourier() );
        order.setTotalPrice( vo.getTotalPrice() );
        order.setBillToFirstName( vo.getBillToFirstName() );
        order.setBillToLastName( vo.getBillToLastName() );
        order.setShipToFirstName( vo.getShipToFirstName() );
        order.setShipToLastName( vo.getShipToLastName() );
        order.setCreditCard( vo.getCreditCard() );
        order.setExpiryDate( vo.getExpiryDate() );
        order.setCardType( vo.getCardType() );
        order.setLocale( vo.getLocale() );
        order.setAlipayOutTradeNo( vo.getAlipayOutTradeNo() );

        return order;
    }

    private OrderStatus orderVoToOrderStatus(OrderVO vo){
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderid( vo.getOrderId() );
        orderStatus.setLinenum( vo.getLineItems().size() );
        orderStatus.setTimestamp( vo.getOrderDate() );
        orderStatus.setStatus( orderStatus.getStatus() );

        return orderStatus;
    }


    @Override
    public CommonResponse<List<OrderVO>> getAllOrder() {
        List<Order> orderList = orderMapper.selectList( null );
        List<OrderVO> orderVOList = new ArrayList<>();
        OrderStatus orderStatus;
        List<LineItem> lineItemList;
        OrderVO orderVO;
        for(Order order : orderList){
            orderStatus = orderStatusMapper.selectById( order.getOrderId() );
            if(orderStatus == null){
                return CommonResponse.createForSuccessMessage( "No order status record in database" );
            }
            QueryWrapper<LineItem> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq( "orderid", order.getOrderId() );
            lineItemList = lineItemMapper.selectList( queryWrapper );
            if(lineItemList.size() != orderStatus.getLinenum() ){
                return CommonResponse.createForSuccessMessage( "Incomplete Lineitem records in database" + "\norderid " + order.getOrderId() );
            }

            orderVO = orderToOrderVO( order, orderStatus, lineItemList );
            orderVOList.add( orderVO );
        }
        return CommonResponse.createForSuccess( orderVOList );

    }

    @Override
    public CommonResponse<OrderVO> insertOrder( OrderVO orderVO ) {
        int result = 1;
        Order order = orderVoToOrder( orderVO );
        result = orderMapper.insert( order );
        if(result != 1){
            CommonResponse.createForSuccessMessage( "Fail to insert entity to Table \"order\"" );
        }
        OrderStatus orderStatus = orderVoToOrderStatus( orderVO );
        result = orderStatusMapper.insert( orderStatus );
        if(result != 1){
            CommonResponse.createForSuccessMessage( "Fail to insert entity to Table \"orderstatus\"" );
        }
        int i = 1;
        for(LineItem lineItem: orderVO.getLineItems()){
            //序号重排
            lineItem.setLinenum( i );
            i ++;
            result = lineItemMapper.insert( lineItem );
            if(result != 1){
                CommonResponse.createForSuccessMessage( "Fail to insert entity to Table \"lineitem\"" );
            }
        }
        //更新Sequence表中的ordernum
        Sequence sequence = sequenceMapper.selectById( "ordernum" );
        sequence.setNextid( sequence.getNextid() + 1 );
        sequenceMapper.updateById( sequence );

        return CommonResponse.createForSuccess(orderVO);

    }

    @Override
    public CommonResponse<OrderVO> getOrder( int orderId ) {
        return null;
    }

    @Override
    public CommonResponse<List<OrderVO>> getOrdersByUsername( String username ) {
        return null;
    }

    @Override
    public CommonResponse<Integer> getNextId( String name ) {
        return null;
    }
}
